/* eslint no-underscore-dangle: 0 */
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import { Button, Table, Icon, Message, Grid, Dialog, Input, Checkbox, Loading } from '@alifd/next';
import IceContainer from '@icedesign/container';
import axios from '../../../../instances/request';
import { withRouter } from 'react-router-dom';
const TableExport = require('tableexport');

const { Row, Col } = Grid;

@withRouter
export default class InspectionDayTable extends Component {
  static displayName = 'InspectionDayTable';

  static propTypes = {
    limit: PropTypes.number,
    type: PropTypes.string,
    title: PropTypes.string,
    isBoweiSupport: PropTypes.bool,
    oid: PropTypes.string,
  };

  static defaultProps = {
    limit: 8,
    isBoweiSupport: false,
  };

  constructor(props) {
    super(props);
    this.state = {
      equipmentList: [],
      tableData: {
        totalCount: 0,
        pageSize: this.props.limit,
        currentPage: 1,
        list: [],
        __loading: true,
      },
      tableWidth: 800,
      value: {},
      loadingVisible: false,
    };
  }

  // todo: 这里不应该将数据请求与返回和组件绑定在一起的，这样做是错误的，应该是数据请求单独是一个函数，组件变换又是一个函数
  async fetchData ({ page }, callback) {
    const tableData = this.state.tableData;
    tableData.__loading = true;

    this.setState({
      tableData
    });

    let res = await axios.post('/inspectionRecord/day/content', {
      oid: this.props.oid
    })
      .catch((err) => {
        Message.error(`巡视记录列表接口${err}`);
        return Promise.reject(err);
      });

    console.log("巡视记录列表接口", res);

    let {code, msg} = res.data;
    switch (code) {
      case 0:
        let {
          inspectionRecords,
          totalCount,
          count,
          daySignatory,
          nightSignatory,
          superSignatory,
          abnormalRecord,
          createdAt,
        } = msg;
        const tableData = this.state.tableData;
        tableData.list = inspectionRecords;
        tableData.totalCount = totalCount;
        tableData.__loading = false;
        this.daySignatory = daySignatory;
        this.nightSignatory = nightSignatory;
        this.superSignatory = superSignatory;
        this.abnormalRecord = abnormalRecord;

        Message.warning('处理时间可能较长，请耐心等待');
        this.setState({
          tableData,
        }, () => {
          this.setExportButton(callback);  // 刷新导出按钮
        });
        return createdAt;
        break;

      default:
        Message.error(`巡视记录列表接口code${code}`);
        return;
    }
  };

  /**
   * 得到设备列表
   * @param page
   * @param limit
   * @param createdAt
   * @return {Promise<{totalCount, equipmentList, count}>}
   */
  async getEquipmentList({ page = 1, limit = -1, beforeTime }) {
    const res = await axios
      .post('/equipment/list', {
        page: page,
        limit: limit,
        sType: this.props.type,
        beforeTime,
      });
    let { code, msg } = res.data;
    if( code !== 0 ) {
      throw new Error(`获取设备列表接口返回code为${code}`);
    }
    let { totalCount, equipmentList, count } = msg;
    return {
      totalCount,
      equipmentList,
      count,
    }
  }

  async componentDidMount() {
    let createdAt = await this.fetchData({ page: 1 });
    let { equipmentList } = await this.getEquipmentList({ limit: -1, beforeTime: createdAt });
    this.setState({
      equipmentList,
      tableWidth: document.body.clientWidth - 290 + 45,
    }, () => {
      this.setExportButton();
    });
  }

  onCheckboxChange(id, EquipmentId, equipmentState) {
    this.setState({
      loadingVisible: true
    }, () => {
      let checkbox_ok = document.getElementById(`checkbox_${id}_ok`).parentNode.parentNode;
      let checkbox_error = document.getElementById(`checkbox_${id}_error`).parentNode.parentNode;
      if(! equipmentState) {
        checkbox_ok.classList.add('checked');
        checkbox_error.classList.remove('checked');
        checkbox_error.style.backgroundColor = 'white';
        checkbox_error.style.color = 'black';
      } else {
        checkbox_ok.classList.remove('checked');
        checkbox_error.classList.add('checked');
        checkbox_error.style.backgroundColor = 'red';
        checkbox_error.style.color = 'white';
      }

      axios.post('/inspectionRecord/update' ,{
        id,
        EquipmentId,
        type: 'day',
        equipmentState,
      }).then((res)=> {
        this.setState({
          loadingVisible: false,
        });
        let { code, msg } = res.data;
        code === 0 ? Message.success('修改成功') : Message.error('修改失败，请刷新页面重试');
      });
    });

  }

  /**
   * 渲染每一行的数据，这里逻辑非常容易出错，应该让后端把数据顺序都处理好，以最方便的形式返回给前端
   */
  renderInspectionData(equipment, isYes, value, i, row) {
    let { id, radios, hours } = equipment;
    let equipmentState = -1;
    let recordId = -1;
    row.records.map((ele, idx) => {
      if( ele.EquipmentId === id ) {
        recordId = ele.id;   // 记录下record的id
        equipmentState = ele.equipmentState;
      }
    });
    // 勾选是的情况: equipmentState为0时；勾选否的情况：equipmentState为1时；都不勾选是equipmentState为-1时
    if( hours.indexOf(row.hour) === -1 ) {
      return null;
    }

    return isYes ? (
      <Checkbox
        id={`checkbox_${recordId}_ok`}
        onChange={this.onCheckboxChange.bind(this, recordId, row.id, 0)}
        style={{ fontSize: '8px', cursor: 'pointer' }}
        label={radios[0]}
        defaultChecked={equipmentState === 0}
        // checked={equipmentState === 0}             // 如果这里用checked，那么点击页面其它地方，className会自动还原
      />
    ) : (
      <Checkbox
        id={`checkbox_${recordId}_error`}
        onChange={this.onCheckboxChange.bind(this, recordId, row.id, 1)}
        style={
          equipmentState === 1 ?
            {fontSize: '8px' ,backgroundColor: 'red', color: 'white', cursor: 'pointer'}:
            {fontSize: '8px', cursor: 'pointer'}
        }
        label={radios[1]}
        defaultChecked={equipmentState === 1}
        // checked={equipmentState === 1}
      />
    );
  }

  /**
   * 渲染列头
   * @param equipmentList
   */
  renderTableColumns(equipmentList) {
    // console.log(equipmentList);

    let equipmentListCombined = [];
    let equipmentScope = [];
    equipmentList.forEach((ele, idx) => {  // 获取所有的scope
      if( equipmentScope.indexOf(ele.scope) === -1 ) {
        equipmentScope.push(ele.scope);
      }
    });
    equipmentScope.forEach((scope, index) => {
      equipmentList.forEach((equipment, idx) => {
        if(equipment.scope === scope) {  // 如果某个设备的scope相同
          equipmentListCombined[index] = equipmentListCombined[index] || {  // 初始化或不变
            equipmentList: [],
            scope,
          };
          equipmentListCombined[index].equipmentList.push(equipment);
        }
      })
    });

    // console.log(equipmentListCombined);

    return equipmentListCombined.map( (equipmentListObj, index) => {
      return  (
        <Table.ColumnGroup
          title={equipmentListObj.scope}
          width={160}
          align='center'
          key='key'
        >
          {
            equipmentListObj.equipmentList.map((equipment, idx) => {
              return <Table.ColumnGroup
                key='key'
                title={ equipment.equipmentname }
                align='center'
                width={160}
              >
                <Table.Column
                  width={80}
                  cell={
                    this
                    .renderInspectionData
                    .bind(
                      this,
                      equipment,
                      true,
                    )
                  }
                />
                <Table.Column
                  width={80}
                  cell={
                    this
                      .renderInspectionData
                      .bind(
                        this,
                        equipment,
                        false,
                      )
                  }
                />
              </Table.ColumnGroup>
            })
          }
        </Table.ColumnGroup>
      )
    });
  }

  /**
   * 渲染导出的表格的每一行数据
   */
  renderExportTableInspectionData(equipment, value, i, row) {
    let { id, radios, hours } = equipment;
    let equipmentState = -1;
    row.records.map((ele, idx) => {
      if( ele.EquipmentId === id ) {
        equipmentState = ele.equipmentState;
      }
    });
    // 勾选是的情况: equipmentState为0时；勾选否的情况：equipmentState为1时；都不勾选是equipmentState为-1时
    if( hours.indexOf(row.hour) === -1 ) {
      return null;
    }
    if( equipmentState === -1 ) {
      return null;
    }

    return (
      <div>{radios[equipmentState] && `${ equipmentState === 0 ? '√' : '☓'}${radios[equipmentState]}`}</div>
    )
  }

  /**
   * 渲染导出表格的表头
   */
  renderExportTableColumns(equipmentList) {
    // console.log(equipmentList);

    let equipmentListCombined = [];
    let equipmentScope = [];
    equipmentList.forEach((ele, idx) => {  // 获取所有的scope
      if( equipmentScope.indexOf(ele.scope) === -1 ) {
        equipmentScope.push(ele.scope);
      }
    });
    equipmentScope.forEach((scope, index) => {
      equipmentList.forEach((equipment, idx) => {
        if(equipment.scope === scope) {  // 如果某个设备的scope相同
          equipmentListCombined[index] = equipmentListCombined[index] || {  // 初始化或不变
            equipmentList: [],
            scope,
          };
          equipmentListCombined[index].equipmentList.push(equipment);
        }
      })
    });

    // console.log(equipmentListCombined);

    return equipmentListCombined.map( (equipmentListObj, index) => {
      return  (
        <Table.ColumnGroup
          title={equipmentListObj.scope}
          width={160}
          align='center'
          key='key'
        >
          {
            equipmentListObj.equipmentList.map((equipment, idx) => {
              return <Table.ColumnGroup
                key='key'
                title={ equipment.equipmentname }
                align='center'
                width={160}
              >
                <Table.Column
                  width={80}
                  cell={
                    this
                      .renderExportTableInspectionData
                      .bind(
                        this,
                        equipment,
                      )
                  }
                />
              </Table.ColumnGroup>
            })
          }
        </Table.ColumnGroup>
      )
    });
  }

  confirmRecord(type) {
    let dialog = Dialog.show({
      isFullScreen: true,
      title: '请输入您的签名',
      content: (
        <div style={{
          ...styles.formItem,
          marginBottom: '40px',
        }}>
          <div style={styles.formLabel}>签名</div>
          <Input
            style={{width: '300px'}}
            placeholder='签名'
            onChange={function(value) {
              this.sign = value;              // todo: 不使用状态机，因为这里状态机已经不堪重负了！
          }.bind(this)}/>
        </div>
      ),
      onOk: () => {
        return axios.post('/inspectionRecord/confirm', {
          oid: this.props.oid,
          sign: this.sign,
          type,
        }).then((res) => {
          let {code} = res.data;
          Message.success('签名成功');
          return this
            .fetchData({page : 1})
            .then(() => {
              dialog.hide();
            });
        });
      },
      onCancel: () => {
        dialog.hide();
      }
    });
  }

  setExportButton(callback) {
    let recordTr = (
      <div id='abnormalRecord'>
        <td>监控异常情况记录：</td>
        <td>{this.abnormalRecord}</td>
      </div>
    );

    let signTr = (
      <div id='signs'>
        <td>IT白班人员签字：</td>
        <td>{this.daySignatory}</td>
        <td>IT夜班人员签字：</td>
        <td>{this.nightSignatory}</td>
        <td>博维Support人员签字：</td>
        <td>{this.superSignatory}</td>
      </div>
    );

    let child;
    if(document.getElementById('abnormalRecord')) {
      child = document.getElementById('abnormalRecord');
      child.parentNode.removeChild(child);
    }
    if(document.getElementById('signs')) {
      child = document.getElementById('signs');
      child.parentNode.removeChild(child);
    }

    let tbody = document.querySelector('#exportTable tbody');
    let tr_record = tbody.appendChild(document.createElement('tr'));
    let tr_sign = tbody.appendChild(document.createElement('tr'));
    ReactDOM.render(recordTr, tr_record, () => {
      ReactDOM.render(signTr, tr_sign, () => {
        let tableId = 'exportTable';
        TableExport(document.getElementById(tableId), {
          formats: ['xlsx'],
          trimWhitespace: false,
          exportButtons: true,
          filename: `${this.props.title}-${this.props.createdTime}`,
        });
        callback && callback();
      })
    });
  }

  /**
   * 导出
   */
  handleExport() {
    this.fetchData({ page : 1 }, () => {      // 更新按钮后再进行点击
      document.getElementsByClassName('button-default xlsx')[0].click();
    });
    // 自定义的方法有些许问题，不如直接模拟点击按钮
    // let XLSX = table.CONSTANTS.FORMAT.XLSX;
    // let exportDataXLSX = table.getExportData()[tableId][XLSX];
    // let bytesXLS = table.getFileSize(exportDataXLSX.data, exportDataXLSX.fileExtension);
    // console.log('filesize (XLSX):', bytesXLS + 'B');
    // table.export2file(exportDataXLSX.data, exportDataXLSX.mimeType, exportDataXLSX.filename, exportDataXLSX.fileExtension);
  }


  // todo: 这里最好不要用state来监听用户输入，否则会很卡，因为这里state监听的数据实在太多太多了！状态树实在太大了！用户会感受到明显的卡顿！
  addAbnormalRecord(e) {
    e.preventDefault();

    let dialog = Dialog.show({
      isFullScreen: true,
      title: '填写当天异常记录',
      content: (
        <div style={{ padding: '10px 15px'}}>
          <Input.TextArea
            style={{width: '300px'}}
            placeholder="如果已有异常记录，重复提交会覆盖原有记录"
            onChange={function(value) {
              this.abnormalRecord = value;
            }.bind(this)}
          />
        </div>
      ),
      onOk: () => {
        return axios.post('/inspectionRecord/abnormal/add', {
          oid: this.props.oid,
          abnormalRecord: this.abnormalRecord,
        }).then((res) => {
          let {code} = res.data;
          Message.success('提交异常记录成功');
          return this
            .fetchData({page : 1})
            .then(() => {
              dialog.hide();
            });
        });
      },
      onCancel: () => {
        dialog.hide();
      }
    })
  }

  render() {
    const tableData = this.state.tableData;
    return (
      <div className="operation-table">
        <Loading visible={this.state.loadingVisible}
                 fullScreen
                 shape="fusion-reactor"
        />
        <IceContainer style={styles.cardContainer}>
           {/*玄学啊，只要一设置display: 'none'或者width: 1, 就导出19KB的有重复行的文件，而不是正常的17KB的文件 */}
          <Table
            id="exportTable"
            dataSource={tableData.list}
            className="basic-table"
            hasBorder={true}
            primaryKey="key"
            style={{ textAlign: 'center', visibility:'hidden', height: '1px',  width: this.state.tableWidth }}
          >
            <Table.Column
              title='巡视时间'
              width={100}
              align='center'
              key='key'
              dataIndex='inspectionTime'
              lock='left'
            />
            {
              this.renderExportTableColumns(this.state.equipmentList)
            }
          </Table>
          <Row>
            <Col>
              <div style={styles.back} onClick={this.props.history.goBack}>
                <Icon type="arrow-left" />返回列表
              </div>
            </Col>
            <Col>
              <div className="operation-table-title" style={styles.operationTableTitle}>
                { this.props.title }
              </div>
            </Col>
            <Col>
              {
                this.props.isBoweiSupport && <Button
                    style={styles.addButton}
                    type='secondary'
                    onClick={this.confirmRecord.bind(this)}
                    size='small'
                  >
                    博维人员签字
                  </Button>
              }
              {
                this.props.isBoweiSupport || <Button
                  style={styles.addButton}
                  type='secondary'
                  onClick={this.confirmRecord.bind(this, 'night')}
                  size='small'
                >
                  夜班签字
                </Button>
              }
              {
                this.props.isBoweiSupport || <Button
                  style={styles.addButton}
                  type='secondary'
                  onClick={this.confirmRecord.bind(this, 'day')}
                  size='small'
                >
                  白班签字
                </Button>
              }
              <Button
                style={{
                  ...styles.addButton,
                  background: '#A2221C',
                  border: '1px solid #A2221C',
                  color: '#f2f2f2',
                }}
                type='default'
                shape="warning"
                size='small'
                onClick={this.addAbnormalRecord.bind(this)}
              >
                填写异常记录
              </Button>
              <Button
                style={{
                  ...styles.addButton,
                  backgroundColor: 'green',
                }}
                className='exportButton'
                type='primary'
                size='small'
                onClick={this.handleExport.bind(this)}
              >
                导出到Excel
              </Button>
            </Col>
          </Row>
          <Row>
            <Col span={24}>
              <div style={{ width: this.state.tableWidth }}>
                <Table
                  isZebra={true}
                  // todo: 左侧aside全屏，右侧content变成scroll以后，表头不再sticky了，很玄学，所以改成固定高度表
                  // stickyHeader={true}
                  fixedHeader={true}
                  maxBodyHeight={350}
                  dataSource={tableData.list}
                  className="basic-table"
                  loading={tableData.__loading}
                  hasBorder={true}
                  primaryKey="key"
                  style={{ textAlign: 'center' }}
                >
                  <Table.Column
                    title='巡视时间'
                    width={100}
                    align='center'
                    key='key'
                    dataIndex='inspectionTime'
                    lock='left'
                  />
                  {
                    this.renderTableColumns(this.state.equipmentList)
                  }
                </Table>
              </div>
            </Col>
          </Row>
          <Row style={styles.tableRow}>
            <Col>
              <div style={{
                marginLeft: '20px',
              }}><p>监控异常情况记录：</p><p>{this.abnormalRecord}</p></div>
            </Col>
          </Row>
          <Row style={styles.tableRow}>
            <Col>
                <span style={{
                  marginLeft: '20px',
                }}>IT白班人员签字：</span>
              <span>
                    {this.daySignatory}
                </span>
            </Col>
            <Col>
                <span style={{
                  marginLeft: '20px',
                }}>IT夜班人员签字：</span>
              <span>
                    {this.nightSignatory}
                </span>
            </Col>
            <Col>
              <span>博维Support人员签字：</span>
              <span>{this.superSignatory}</span>
            </Col>
          </Row>
        </IceContainer>
      </div>
    )
  }
}

const styles = {
  back: {
    margin: '10px 0 30px 10px',
    fontSize: '18px',
    fontWeight: '500',
    color: '#5584FF',
    cursor: 'pointer',
  },
  cardContainer: {
    padding: '10px 10px 20px 10px',
  },
  titleCol: {
    display: 'flex',
    flexDirection: 'row',
  },
  operBtn: {
    display: 'inline-block',
    width: '24px',
    height: '24px',
    borderRadius: '999px',
    color: '#929292',
    background: '#f2f2f2',
    textAlign: 'center',
    cursor: 'pointer',
    lineHeight: '24px',
    marginRight: '6px',
  },
  paginationContainer: {
    textAlign: 'right',
    paddingTop: '26px',
  },
  operationTableTitle: {
    fontSize: '18px',
    fontWeight: 'bold',
    fontColor: 'black',
    height: '45px',
    lineHeight: '45px',
    textAlign: 'center',
  },
  addButton: {
    float: 'right',
    margin: '14px 15px 0 0',
  },
  formItem: {
    display: 'flex',
    alignItems: 'center',
    margin: '10px 40px',
    float: 'right',
  },
  formLabel: {
    minWidth: '60px',
  },
  tableRow: {
    background: '#FFFFFF',
    color: '#333333',
    fontSize: '14px',
    border: '1px solid #DCDEE3',
    borderTop: 'none',
    padding: '10px 10px',
  },

};
